﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Nox.Amuse.Model;
using Nox.Amuse.MVVM;
using System.Windows.Input;
using Nox.Amuse.View;

namespace Nox.Amuse.ViewModel
{
    public class CommandHistoryViewModel : ObservableObject
    {
        private ObservableCollection<CommandHistoryItemViewModel> myCommandHistoryItems = new ObservableCollection<CommandHistoryItemViewModel>();
        public ObservableCollection<CommandHistoryItemViewModel> CommandHistoryItems
        {
            get
            {
                return myCommandHistoryItems;
            }
        }

        private int mySelectedHistoryIndex;
        public int SelectedHistoryIndex
        {
            get { return mySelectedHistoryIndex; }
            set
            {
                mySelectedHistoryIndex = value;
                this.RaisePropertyChanged("SelectedHistoryIndex");
            }
        }

        private CommandHistoryItemViewModel mySelectedHistoryItem;
        public CommandHistoryItemViewModel SelectedHistoryItem
        {
            get { return mySelectedHistoryItem; }
            set
            {
                mySelectedHistoryItem = value;
                this.RaisePropertyChanged("SelectedHistoryItem");
            }
        }

        private Session mySession;

        public void UpdateSession(Session session)
        {
            mySession = session;
        }

        public void RecordCommand(CommandHistoryItem chi)
        {
            var item = new CommandHistoryItemViewModel(chi);
            item.RegisterParent(this);
            myCommandHistoryItems.Add(item);
            SelectedHistoryItem = myCommandHistoryItems.Last();
        }

        public event EventHandler CommandRecalled;
        private void OnCommandRecalled()
        {
            EventHandler safe = CommandRecalled;
            if (safe != null)
                safe(this, new EventArgs());
        }

        public ICommand RecallCommand
        {
            get
            {
                return myRecallCommand ?? (myRecallCommand = new RelayCommand(
                    () =>
                    {
                        OnCommandRecalled();
                    },
                    () =>
                    {
                        return SelectedHistoryItem != null;
                    }
                    ));
            }
        }
        private RelayCommand myRecallCommand;

        /// <summary>
        /// Performs a recall when requested by a child who was just double-clicked
        /// </summary>
        public void ChildRecallCommand()
        {
            RecallCommand.Execute(null);
        }


        public ICommand SendCommand
        {
            get
            {
                return mySendCommand ?? (mySendCommand = new RelayCommand(
                    () =>
                    {
                        mySession.SendCommand(mySelectedHistoryItem.OriginalString);
                        RecordCommand(new CommandHistoryItem(mySelectedHistoryItem.OriginalString));
                    },
                    () =>
                    {
                        return SelectedHistoryItem != null && mySession.Status == SessionStatus.Connected;
                    }
                    ));
            }
        }
        private RelayCommand mySendCommand;

        public ICommand ClearCommand
        {
            get
            {
                return myClearCommand ?? (myClearCommand = new RelayCommand(
                    () =>
                    {
                        myCommandHistoryItems.Clear();
                    },
                    () =>
                    {
                        return myCommandHistoryItems.Count > 0;
                    }
                    ));
            }
        }
        private RelayCommand myClearCommand;

        public event EventHandler ExternalHistoryWindowOpened;
        private void OnExternalHistoryWindowOpened()
        {
            EventHandler safe = ExternalHistoryWindowOpened;
            if (safe != null)
                safe(this, new EventArgs());
        }

        CommandHistoryWindow externalWindow;

        public ICommand OpenHistoryWindowCommand
        {
            get
            {
                return myOpenHistoryWindowCommand ?? (myOpenHistoryWindowCommand = new RelayCommand(
                    () =>
                    {
                        if (externalWindow == null)
                        {
                            externalWindow = new CommandHistoryWindow { DataContext = this, Owner = this.GetViewModelWindow() };
                            externalWindow.Show();
                        }
                        else
                        {
                            externalWindow.Activate();
                            if (!externalWindow.IsActive)
                            {
                                // If the window failed to activate, its probably been closed, recreate it
                                externalWindow = new CommandHistoryWindow { DataContext = this, Owner = this.GetViewModelWindow() };
                                externalWindow.Show();
                            }
                        }
                        OnExternalHistoryWindowOpened();
                    }
                    ));
            }
        }
        private RelayCommand myOpenHistoryWindowCommand;
    }
}
